package br.com.iswe.gwt.ui.client.base;

import java.util.List;
import java.util.Map;

import br.com.iswe.gwt.ui.client.DetailPopupPanel;
import br.com.iswe.gwt.ui.client.MessagePanel;
import br.com.iswe.gwt.ui.client.PnBotoesDetail;
import br.com.iswe.gwt.util.client.CallBackList;
import br.com.iswe.gwt.util.client.CommonConstants;

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.DockPanel;
import com.google.gwt.user.client.ui.Hyperlink;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.Widget;

public abstract class BaseListaDetailPanel extends DockPanel {

	protected static final String LISTA_DETAIL_PANEL = "listaDetailPanel";

	//I18N
	protected final CommonConstants commonConstants = (CommonConstants) GWT.create(CommonConstants.class);
	
	//Injetados pelo construtor
	
	protected final MessagePanel messagePanel;
	
	protected final Hyperlink linkAdicionar = new Hyperlink(commonConstants.adicionar(), CommonConstants.ADICIONAR);
	
	protected final String nomeLista;
	
	protected DetailPopupPanel detailPopupPanel = null;
	
	protected Hyperlink link;
	protected String titulo;
	
	public CallBackList posSalvarCallback = new CallBackList();
	public CallBackList posDeletarCallback = new CallBackList();
	
	
	public BaseListaDetailPanel(String nomeLista, String titulo){
		this.messagePanel = MessagePanel.getInstance();
		this.nomeLista = nomeLista;
		this.titulo = titulo;
	}
	
	public BaseListaDetailPanel(MessagePanel messagePanel, String nomeLista, String titulo){
		this.messagePanel = MessagePanel.getInstance();
		this.nomeLista = nomeLista;
		this.titulo = titulo;
	}
	
	private BaseListaPanel listaPanel;
	public BaseListaPanel getListaPanel(){
		if(listaPanel == null){
			listaPanel = buildListaPanel();
		}
		return listaPanel;
	}
	protected abstract BaseListaPanel buildListaPanel();

	private ClickListener fecharListener;
	protected ClickListener getFecharListener(){
		if(fecharListener == null){
			fecharListener = buildFecharListener();
		}
		return fecharListener;
	}
	protected ClickListener buildFecharListener() {
		return new ClickListener(){
			public void onClick(Widget sender) {
				//Esconde o painel de lista e mostra o link.
				setVisible(false);
				if(link != null){
					link.setVisible(true);
				}
			}	
		};
	}
	
	protected PnBotoesDetail botoesDetail;
	
	protected ScrollPanel scrollPanel;
	
	protected void initLayout() {
		addStyleName(LISTA_DETAIL_PANEL);
		
		//Painel de botoes dos paineis mestre detalhe
		Label lbTitulo = new Label(titulo);
		botoesDetail = new PnBotoesDetail(lbTitulo, linkAdicionar, getFecharListener());
		linkAdicionar.addClickListener(getAdicionarListener());
		add(botoesDetail, DockPanel.NORTH);
		
		//Lista dentro do scroll
		BaseListaPanel listaPanel = getListaPanel();
		//listaPanel.setPosDetalharListener(getDetalharListener());
		listaPanel.setDetalharListener(getDetalharListener());
		scrollPanel = new ScrollPanel();
		scrollPanel.addStyleName(CommonConstants.SCROLL_PANEL);
		scrollPanel.add(listaPanel);
		//adiciona no centro
		add(scrollPanel, DockPanel.CENTER);
		
		//Inicia sem visibilidade
		setVisible(false);
	}
	
	public void reset() {
		setVisible(false);
		getListaPanel().reset();
	}
	
	public DetailPopupPanel getDetailPopupPanel() {
		if(detailPopupPanel == null){
			BaseDetalhePanel detalhePanel = buildDetalhePanel();
			detailPopupPanel = new DetailPopupPanel(detalhePanel);
			detailPopupPanel.setText(getTituloPopUpDetalhe());
			detalhePanel.posSalvarCallback.add( posSalvarCallBack );
			detalhePanel.posDeletarCallback.add( posDeletarCallBack );
		}
		return detailPopupPanel;
	}
	

	////////////////////////////////////
	///// Callbacks
	////////////////////////////////////
	protected final AsyncCallback posSalvarCallBack = new AsyncCallback(){
		public void onFailure(Throwable caught){
			//chama os eventos
			posSalvarCallback.onFailure(caught);
		}
		public void onSuccess(Object result) {
			//apos salvar esconde o painel de detalhe de Documento Pessoa.
			getDetailPopupPanel().hide();
			//recarrega a lista
			getListaPanel().reset();
			consultar();
			//chama os eventos
			posSalvarCallback.onSuccess(result);
		}
	};
	
	protected final AsyncCallback posDeletarCallBack = new AsyncCallback(){
		public void onFailure(Throwable caught){
			//chama os eventos
			posDeletarCallback.onFailure(caught);
		}
		public void onSuccess(Object result) {
			//apos deletar esconde o painel de detalhe
			getDetailPopupPanel().hide();
			//recarrega a lista
			getListaPanel().reset();
			consultar();
			//chama os eventos
			posDeletarCallback.onSuccess(result);
		}
	};
	
	protected final AsyncCallback detalharCallBack = new AsyncCallback(){
		public void onFailure(Throwable caught) {
			messagePanel.showMessage(commonConstants.erroDetalhar(), MessagePanel.ERRO);
		}
		public void onSuccess(Object result) {
			//Detalha os dados do mestre/master.
			List dados = (List)result;
			if(dados.size() > 0){
				Map bean = (Map)dados.get(0);
				List listaDetail = (List)bean.get(nomeLista);
				getListaPanel().reset();
				getListaPanel().populate(listaDetail);
			}
			else{
				messagePanel.showMessage(commonConstants.erroDetalhar(), MessagePanel.ERRO);
			}
		}
	};
	
	/**
	 * Detalhar Listener
	 */
	private ClickListener detalharListener;
	protected ClickListener getDetalharListener() {
		if(detalharListener == null){
			detalharListener = buildDetalharListener();
		}
		return detalharListener;
	}
	public void setDetalharListener(ClickListener listener) {
		this.detalharListener = listener;
	}
	
	protected abstract ClickListener buildDetalharListener();
	
	
	
	public abstract void consultar();

	protected abstract String getTituloPopUpDetalhe();
	
	protected abstract BaseDetalhePanel buildDetalhePanel();
	
	protected abstract ClickListener getAdicionarListener();
	
	public Hyperlink getLink() {
		return link;
	}
	public void setLink(Hyperlink link) {
		this.link = link;
	}
	
	public void showBotaoFechar(boolean value) {
		botoesDetail.btoFechar.setVisible(value);
	}
	
	public void setHeight(String height) {
		super.setHeight(height);
		scrollPanel.setHeight(height);
		getListaPanel().setHeight(height);
	}
	
	public void setWidth(String width) {
		super.setWidth(width);
		scrollPanel.setWidth(width);
		getListaPanel().setWidth(width);
	}
	
}
